package chai.ning.string;

import java.lang.reflect.Array;
import java.lang.reflect.Field;

public class AnalyseStringHelper {
	
	private static Class<?> stringClass = String.class;
	
	private static Field valueField ;
	
	private static Field coderField ;
	
	private static Field hashField ;
	
	static {
		try {
			valueField = stringClass.getDeclaredField( "value" );
			valueField.setAccessible( true );
			
			coderField = stringClass.getDeclaredField( "coder" );
			coderField.setAccessible( true );
			
			hashField = stringClass.getDeclaredField( "hash" );
			hashField.setAccessible( true );
		} catch ( Exception e) {
			e.printStackTrace();
		}
		
	}
	
	/**
	 * [针对JDK9之后的String类设计来查看任意String实例内部的结构]
	 * @param s 被解析String实例
	 */
	public static void show( String s ) {
		if( s != null ) {
			try {
				Object o = valueField.get( s );
				String x = toString( o );
				Object c = coderField.get( s );
				Object h = hashField.get( s );
				System.out.println( "value : " + x + " , coder : " + c + " , hash : " + h);
			} catch ( Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	private static String toString( Object o ) {
		String s = "[" ;
		if( o != null && o.getClass().isArray() ) {
			for( int i = 0 , n = Array.getLength( o ) ; i < n ; i++ ) {
				s += Array.get( o ,  i ) ;
				if( i != n - 1 ) {
					s += ",";
				}
			}
		}
		s += "]" ;
		return s ;
	}

	/**
	 * [为指定Stirng实例内部的byte数组的指定位置更换字节]
	 * @param s 需要执行更换操作的字符串引用
	 * @param x 被替换的byte数组的索引(数组下标)
	 * @param b 替换后的字节
	 */
	public static void setByte( String s , int x , byte b ) {
		if( s != null ) {
			try {
				Object o = valueField.get( s );
				int n = Array.getLength( o );
				if( x >= 0 && x < n ) {
					Array.set( o ,  x ,  b );
				}
			} catch ( Exception e) {
				e.printStackTrace();
			}
		}
	}

	public static void setHash( String s , int hash ) {
		if( s != null ) {
			try {
				hashField.set( s ,  hash );
			} catch ( Exception e) {
				e.printStackTrace();
			}
		}
	}
}
